package modbus

import (
	"encoding/json"
	"fmt"
	http_client "modbus-dtu-plugin/http_client"
	"modbus-dtu-plugin/zaplog"

	"go.uber.org/zap"
)

type DeviceConfig struct {
	GatewayId       string //网关设备id
	DeviceId        string //子设备id
	AccessToken     string //子设备token
	DeviceAddress   uint8  //设备地址
	FunctionCode    uint8  //功能码
	StartingAddress uint16 //起始地址
	AddressNum      uint16 //地址数量（地址数量返现，根据数据类型后面的数字除以2，比如int32-4的地址数量就是2）
	Key             string //属性名（如：temp,hum等）
	DataType        string //数据类型（3和6功能码的数据类型：int16-2 uint16-2 int32-4 uint32-4 int64-8（一个地址2字节））；uint64在转换中会丢失精度，uint32在转float时候某些值也会丢失精度
	Equation        string
	Precision       string
	ServerAddr      string //DTU地址
	ByteOrder       string //字节序 big little
}
type SubDevice struct {
	AccessToken   string //子设备token
	DeviceConfig  DeviceConfig
	DeviceId      string
	SubDeviceAddr string
}
type Gateway struct {
	Id           string      //网关设备id
	ProtocolType string      //modbus协议类型：RTU TCP
	AccessToken  string      //网关设备token
	SubDevice    []SubDevice //子设备
}
type GatewayData struct {
	Code    int       `json:"code"`
	Message string    `json:"message"`
	Data    []Gateway `json:"data"`
}

// 网关配置列表
var GatewayConfigList Gateway

// gateway_id -> conn
var GatewayConn = make(map[string]*ModbusClient)

func StartModbus(protocol string) {
	fmt.Println("**************************", protocol)
	// 请求 01 03 00 01 00 04 c9 15  010300010004c915
	// 响应 01 03 04 00 00 00 00 00 00 00 19 A7 F3 01030400000000000000191D01
	// gateway := Gateway{
	// 	Id:           "001",
	// 	ProtocolType: "MODBUS_RTU_REPORT", //MODBUS_RTU MODBUS_TCP
	// 	AccessToken:  "123456",
	// 	SubDevice: []SubDevice{
	// 		{
	// 			DeviceId:        "001",
	// 			AccessToken:     "654321",
	// 			DeviceAddress:   1, //设备地址
	// 			FunctionCode:    3, //功能码
	// 			StartingAddress: 1, //起始地址
	// 			Key:             "temp",
	// 			AddressNum:      4,
	// 			DataType:        "int64-8",
	// 			ServerAddr:      "127.0.0.1:502",
	// 			ByteOrder:       "big",
	// 		},
	// 		{
	// 			DeviceId:        "002",
	// 			AccessToken:     "654322",
	// 			DeviceAddress:   1, //设备地址
	// 			FunctionCode:    3, //功能码
	// 			StartingAddress: 5, //起始地址
	// 			Key:             "temp",
	// 			AddressNum:      4,
	// 			DataType:        "int64-8",
	// 			ServerAddr:      "127.0.0.1:502",
	// 			ByteOrder:       "big",
	// 		},
	// 	},
	// }
	// 通过接口获取网关配置
	var req = http_client.GetAllGatewayConfigReq{
		ProtocolType: protocol,
		DeviceType:   "2",
	}
	rsp, err := http_client.ApiGetAllGatewayConfig(req)
	if err != nil {
		zaplog.Logger.Error("get gateway config failed", zap.Error(err))
		return
	}
	var gateway_data GatewayData
	json_error := json.Unmarshal(rsp, &gateway_data)
	if json_error != nil {
		zaplog.Logger.Error("json unmarshal failed", zap.Error(json_error))
		return
	}
	for _, gateway := range gateway_data.Data {
		fmt.Println(gateway)
		//遍历网关配置
		for i := 0; i < len(gateway.SubDevice); i++ {
			gateway.SubDevice[i].DeviceConfig.GatewayId = gateway.Id
		}
		HandleGatewayConfig(gateway)
	}
}

// 处理单个网关配置
func HandleGatewayConfig(gateway Gateway) {
	var subDeviceRequestMap = make(map[string]SubDevice)

	// 遍历网关下的子设备
	for _, device := range gateway.SubDevice {
		// 拼接key
		key := fmt.Sprintf("%d_%d_%d", device.DeviceConfig.DeviceAddress, device.DeviceConfig.FunctionCode, device.DeviceConfig.StartingAddress)
		// 将子设备添加到map中
		subDeviceRequestMap[key] = device

	}
	// 连接DTU
	var mode string
	if gateway.ProtocolType == "MODBUS_RTU_REPORT" {
		mode = "RTU"
	} else if gateway.ProtocolType == "MODBUS_TCP_REPORT" {
		mode = "TCP"
	} else {
		fmt.Println("不支持的协议类型")
		return
	}
	var modbusClient ModbusClient
	// 判断gateway.SubDevice是否为空
	if len(gateway.SubDevice) == 0 {
		fmt.Println("网关下没有子设备")
		return
	}
	mc := modbusClient.NewModbusClient(mode, gateway.SubDevice[0].DeviceConfig.ServerAddr, subDeviceRequestMap, gateway.AccessToken)
	GatewayConn[gateway.Id] = mc
	mc.Connect()
}
